﻿using Sidvall.WorkItemManager.Workflow.Conditions;

namespace Sidvall.WorkItemManager.Data.ConfigModel.EntityManagers
{
	public partial class ScheduleManager<TEntity, TList>
	{
		#region Public Members

		#region GetNextExecutionTime

		public System.DateTime? GetNextExecutionTime(ISchedule item, System.DateTime time, System.DateTime? lastExecutionTime)
		{
			System.DateTime? dayEndTime, dayStartTime, tempTime;
			System.DateTime startTime;
			int day;

			if (item == null)
				throw new System.ArgumentNullException("item");

			// Initialize
			startTime = item.StartTime.ToLocalTime();
			time = time.ToLocalTime();
			if (startTime > time)
				time = startTime;
			if (lastExecutionTime != null)
				lastExecutionTime = lastExecutionTime.Value.ToLocalTime();
			if (item.DayEndTime != null)
				dayEndTime = item.DayEndTime.Value.ToLocalTime();
			else
				dayEndTime = null;
			if (item.DayStartTime != null)
				dayStartTime = item.DayStartTime.Value.ToLocalTime();
			else
				dayStartTime = null;

			if (IsExpired(startTime, item.EndDate, time))
				return null;
			day = 0;
			switch (item.ScheduleFrequencyTypeId)
			{
				case ScheduleFrequencyType.Monthly:
					while (day != time.Day)
					{
						tempTime = GetTimeWithValidDay(startTime, item.EndDate, item.ScheduleFrequency, item.MonthFrequencyTypeId, item.MonthFrequency, time);
						if (tempTime == null)
							return null;
						time = tempTime.Value;
						if (IsExpired(startTime, item.EndDate, time))
							return null;
						day = time.Day;
						time = GetTimeWithValidTime(dayStartTime, dayEndTime, lastExecutionTime, item.DayFrequencyTypeId, item.DayFrequency, time);
						if (IsExpired(startTime, item.EndDate, time))
							return null;
					}
					break;
				case ScheduleFrequencyType.Weekly:
					while (day != time.Day)
					{
						tempTime = GetTimeWithValidDay(startTime, item.EndDate, item.ScheduleFrequency, item.Monday, item.Tuesday, item.Wednesday, item.Thursday, item.Friday, item.Saturday, item.Sunday, time);
						if (tempTime == null)
							return null;
						time = tempTime.Value;
						if (IsExpired(startTime, item.EndDate, time))
							return null;
						day = time.Day;
						time = GetTimeWithValidTime(dayStartTime, dayEndTime, lastExecutionTime, item.DayFrequencyTypeId, item.DayFrequency, time);
						if (IsExpired(startTime, item.EndDate, time))
							return null;
					}
					break;
				case ScheduleFrequencyType.Daily:
					while (day != time.Day)
					{
						time = GetTimeWithValidDay(startTime, item.ScheduleFrequency, time);
						if (IsExpired(startTime, item.EndDate, time))
							return null;
						day = time.Day;
						time = GetTimeWithValidTime(dayStartTime, dayEndTime, lastExecutionTime, item.DayFrequencyTypeId, item.DayFrequency, time);
						if (IsExpired(startTime, item.EndDate, time))
							return null;
					}
					break;
				default:
					if (lastExecutionTime != null)
						return null;
					break;
			}
			return time.ToLocalTime();
		}

		#endregion
		#region GetScheduleDescription

		public string GetScheduleDescription(ISchedule item)
		{
			string description, dayStartTimeString, dayEndTimeString;
			System.DateTime? dayEndTime, dayStartTime;
			System.DateTime startTime;

			if (item == null)
				return null;

			// Initialize
			startTime = item.StartTime.ToLocalTime();
			if (item.DayEndTime != null)
				dayEndTime = item.DayEndTime.Value.ToLocalTime();
			else
				dayEndTime = null;
			if (item.DayStartTime != null)
				dayStartTime = item.DayStartTime.Value.ToLocalTime();
			else
				dayStartTime = null;

			if (dayStartTime != null)
				dayStartTimeString = dayStartTime.Value.ToString("HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
			else
				dayStartTimeString = "00:00:00";
			if (dayEndTime != null)
				dayEndTimeString = dayEndTime.Value.ToString("HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
			else
				dayEndTimeString = "23:59:59";
			switch (item.ScheduleFrequencyTypeId)
			{
				case ScheduleFrequencyType.Monthly:
					if (item.ScheduleFrequency == 1)
						description = "Occurs every month";
					else
						description = "Occurs every " + item.ScheduleFrequency.ToString(System.Globalization.CultureInfo.InvariantCulture) + " months";
					description += " on " + GetDescription(item.MonthFrequencyTypeId, item.MonthFrequency);
					break;
				case ScheduleFrequencyType.Weekly:
					if (item.ScheduleFrequency == 1)
						description = "Occurs every week";
					else
						description = "Occurs every " + item.ScheduleFrequency.ToString(System.Globalization.CultureInfo.InvariantCulture) + " weeks";
					string weekDays = GetDescription(item.Monday, item.Tuesday, item.Wednesday, item.Thursday, item.Friday, item.Saturday, item.Sunday);
					if (string.IsNullOrEmpty(weekDays) == false)
						description += " on " + weekDays;
					break;
				case ScheduleFrequencyType.Daily:
					if (item.ScheduleFrequency == 1)
						description = "Occurs every day";
					else
						description = "Occurs every " + item.ScheduleFrequency.ToString(System.Globalization.CultureInfo.InvariantCulture) + " days";
					break;
				default:
					return "Occurs on " + startTime.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture) + " at " + startTime.ToString("HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture) + ".";
			}
			switch (item.DayFrequencyTypeId)
			{
				case DayFrequencyType.Onetime:
					description += " at " + dayStartTimeString + ".";
					break;
				default:
					description += " every " + GetDescription(item.DayFrequencyTypeId, item.DayFrequency) + " between " + dayStartTimeString + " and " + dayEndTimeString + ".";
					break;
			}
			if (item.EndDate == null)
				description += " Schedule will be used starting on " + startTime.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture) + ".";
			else
				description += " Schedule will be used between " + startTime.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture) + " and " + item.EndDate.Value.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture) + ".";
			return description;
		}

		#endregion
		#region IsExecutionTime

		public bool IsExecutionTime(ISchedule item, System.DateTime time, System.DateTime? lastExecutionTime)
		{
			System.DateTime? dayEndTime, dayStartTime;
			System.DateTime startTime;

			if (item == null)
				throw new System.ArgumentNullException("item");

			// Initialize
			startTime = item.StartTime.ToLocalTime();
			time = time.ToLocalTime();
			if (lastExecutionTime != null)
				lastExecutionTime = lastExecutionTime.Value.ToLocalTime();
			if (item.DayEndTime != null)
				dayEndTime = item.DayEndTime.Value.ToLocalTime();
			else
				dayEndTime = null;
			if (item.DayStartTime != null)
				dayStartTime = item.DayStartTime.Value.ToLocalTime();
			else
				dayStartTime = null;

			if (startTime > time)
				return false;
			if (IsExpired(startTime, item.EndDate, time))
				return false;
			switch (item.ScheduleFrequencyTypeId)
			{
				case ScheduleFrequencyType.Monthly:
					int monthCount = GetNumberOfMonths(startTime, time);
					if (monthCount % item.ScheduleFrequency != 0)
						return false;
					if (!IsExecutionTime(item.MonthFrequencyTypeId, item.MonthFrequency, time))
						return false;
					break;
				case ScheduleFrequencyType.Weekly:
					int weekCount = GetNumberOfWeeks(startTime, time);
					if (weekCount % item.ScheduleFrequency != 0)
						return false;
					if (!IsExecutionTime(item.Monday, item.Tuesday, item.Wednesday, item.Thursday, item.Friday, item.Saturday, item.Sunday, time))
						return false;
					break;
				case ScheduleFrequencyType.Daily:
					int dayCount = GetNumberOfDays(startTime, time);
					if (dayCount % item.ScheduleFrequency != 0)
						return false;
					break;
				default:
					return (lastExecutionTime == null);
			}
			if ((dayStartTime != null) && (dayStartTime.Value.TimeOfDay > time.TimeOfDay))
				return false;
			else if ((dayEndTime != null) && (dayEndTime.Value.TimeOfDay < time.TimeOfDay))
				return false;
			return IsExecutionTime(dayStartTime, item.DayFrequencyTypeId, item.DayFrequency, time, lastExecutionTime);
		}

		#endregion

		#endregion
		#region Private Members

		#region GetDescription

		private static string GetDescription(MonthFrequencyType monthFrequencyType, byte monthFrequency)
		{
			string position;

			switch (monthFrequency)
			{
				case 1:
					position = "first";
					break;
				case 2:
					position = "second";
					break;
				case 3:
					position = "third";
					break;
				case 4:
					position = "forth";
					break;
				default:
					position = "last";
					break;
			}
			switch (monthFrequencyType)
			{
				case MonthFrequencyType.Monday:
					return position + " Monday";
				case MonthFrequencyType.Tuesday:
					return position + " Tuesday";
				case MonthFrequencyType.Wednesday:
					return position + " Wednesday";
				case MonthFrequencyType.Thursday:
					return position + " Thursday";
				case MonthFrequencyType.Friday:
					return position + " Friday";
				case MonthFrequencyType.Saturday:
					return position + " Saturday";
				case MonthFrequencyType.Sunday:
					return position + " Sunday";
				case MonthFrequencyType.Day:
					return "day " + monthFrequency.ToString(System.Globalization.CultureInfo.InvariantCulture);
				case MonthFrequencyType.Weekday:
					return position + " weekday";
				case MonthFrequencyType.Weekend:
					return position + " weekend";
				default:
					return "";
			}
		}
		private static string GetDescription(DayFrequencyType dayFrequencyType, byte dayFrequency)
		{
			switch (dayFrequencyType)
			{
				case DayFrequencyType.EveryHour:
					if (dayFrequency == 1)
						return "hour";
					else
						return dayFrequency.ToString(System.Globalization.CultureInfo.InvariantCulture) + " hours";
				case DayFrequencyType.EveryMinute:
					if (dayFrequency == 1)
						return "minute";
					else
						return dayFrequency.ToString(System.Globalization.CultureInfo.InvariantCulture) + " minutes";
				case DayFrequencyType.EverySecond:
					if (dayFrequency == 1)
						return "second";
					else
						return dayFrequency.ToString(System.Globalization.CultureInfo.InvariantCulture) + " seconds";
				default:
					return "";
			}
		}
		private static string GetDescription(bool monday, bool tuesday, bool wednesday, bool thursday, bool friday, bool saturday, bool sunday)
		{
			string weekDays = string.Empty;
			if (monday == true)
			{
				if (string.IsNullOrEmpty(weekDays) == false)
					weekDays += ", ";
				weekDays += "Monday";
			}
			if (tuesday == true)
			{
				if (string.IsNullOrEmpty(weekDays) == false)
					weekDays += ", ";
				weekDays += "Tuesday";
			}
			if (wednesday == true)
			{
				if (string.IsNullOrEmpty(weekDays) == false)
					weekDays += ", ";
				weekDays += "Wednesday";
			}
			if (thursday == true)
			{
				if (string.IsNullOrEmpty(weekDays) == false)
					weekDays += ", ";
				weekDays += "Thursday";
			}
			if (friday == true)
			{
				if (string.IsNullOrEmpty(weekDays) == false)
					weekDays += ", ";
				weekDays += "Friday";
			}
			if (saturday == true)
			{
				if (string.IsNullOrEmpty(weekDays) == false)
					weekDays += ", ";
				weekDays += "Saturday";
			}
			if (sunday == true)
			{
				if (string.IsNullOrEmpty(weekDays) == false)
					weekDays += ", ";
				weekDays += "Sunday";
			}
			return weekDays;
		}

		#endregion
		#region GetNumberOfDays

		private static int GetNumberOfDays(System.DateTime startDate, System.DateTime endDate)
		{
			return endDate.Subtract(startDate).Days;
		}

		#endregion
		#region GetNumberOfMonths

		private static int GetNumberOfMonths(System.DateTime startDate, System.DateTime endDate)
		{
			return (endDate.Year - startDate.Year) * 12 + endDate.Month - startDate.Month;
		}

		#endregion
		#region GetNumberOfWeeks

		private static int GetNumberOfWeeks(System.DateTime startDate, System.DateTime endDate)
		{
			int weekCount = endDate.Subtract(startDate).Days / 7;
			if (System.Globalization.CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(startDate.AddDays(7 * weekCount), System.Globalization.CalendarWeekRule.FirstFourDayWeek, System.DayOfWeek.Monday) !=
			  System.Globalization.CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(endDate, System.Globalization.CalendarWeekRule.FirstFourDayWeek, System.DayOfWeek.Monday))
			{
				weekCount += 1;
			}
			return weekCount;
		}

		#endregion
		#region GetTimeWithValidMonth

		private static System.DateTime GetTimeWithValidMonth(System.DateTime startTime, byte scheduleFrequency, System.DateTime time)
		{
			int monthCount, validMonthCount;

			monthCount = GetNumberOfMonths(startTime, time);
			if ((monthCount % scheduleFrequency) == 0)
				return time;

			validMonthCount = (1 + (monthCount / scheduleFrequency)) * scheduleFrequency;
			time = time.AddMonths(validMonthCount - monthCount);

			return new System.DateTime(time.Year, time.Month, 1, 0, 0, 0, System.DateTimeKind.Local);
		}

		#endregion
		#region GetTimeWithValidDay

		private static System.DateTime? GetTimeWithValidDay(System.DateTime startTime, System.DateTime? endDate, byte scheduleFrequency, MonthFrequencyType monthFrequencyType, byte monthFrequency, System.DateTime time)
		{
			int currentMonth;
			bool isValid;

			currentMonth = 0;
			isValid = false;
			while (!isValid)
			{
				if (currentMonth != time.Month)
					time = GetTimeWithValidMonth(startTime, scheduleFrequency, time);
				currentMonth = time.Month;
				if (!IsExecutionTime(monthFrequencyType, monthFrequency, time))
				{
					time = time.AddDays(1);
					time = new System.DateTime(time.Year, time.Month, time.Day, 0, 0, 0, System.DateTimeKind.Local);
				}
				else
					isValid = true;
				if (IsExpired(startTime, endDate, time))
					return null;
			}

			return time;
		}
		private static System.DateTime? GetTimeWithValidDay(System.DateTime startTime, System.DateTime? endDate, byte scheduleFrequency, bool monday, bool tuesday, bool wednesday, bool thursday,
			bool friday, bool saturday, bool sunday, System.DateTime time)
		{
			int day, weekCount, validWeekCount;
			bool isValid;

			day = 0;
			isValid = false;
			while (!isValid)
			{
				if (day != time.Day)
				{
					weekCount = GetNumberOfWeeks(startTime, time);
					if ((weekCount % scheduleFrequency) != 0)
					{
						validWeekCount = (1 + (weekCount / scheduleFrequency)) * scheduleFrequency;
						time = time.AddDays((validWeekCount - weekCount) * 7);
						time = new System.DateTime(time.Year, time.Month, time.Day, 0, 0, 0, System.DateTimeKind.Local);
					}
				}
				day = time.Day;
				if (!IsExecutionTime(monday, tuesday, wednesday, thursday, friday, saturday, sunday, time))
				{
					time = time.AddDays(1);
					time = new System.DateTime(time.Year, time.Month, time.Day, 0, 0, 0, System.DateTimeKind.Local);
				}
				else
					isValid = true;
				if (IsExpired(startTime, endDate, time))
					return null;
			}

			return time;
		}
		private static System.DateTime GetTimeWithValidDay(System.DateTime startTime, byte scheduleFrequency, System.DateTime time)
		{
			int dayCount, validDayCount;

			dayCount = GetNumberOfDays(startTime, time);
			if (dayCount % scheduleFrequency == 0)
				return time;

			validDayCount = (1 + (dayCount / scheduleFrequency)) * scheduleFrequency;
			time = time.AddDays(validDayCount - dayCount);

			return new System.DateTime(time.Year, time.Month, time.Day, 0, 0, 0, System.DateTimeKind.Local);
		}

		#endregion
		#region GetTimeWithValidTime

		private static System.DateTime GetTimeWithValidTime(System.DateTime? dayStartTime, System.DateTime? dayEndTime, System.DateTime? lastExecutionTime, DayFrequencyType dayFrequencyType,
			byte dayFrequency, System.DateTime time)
		{
			System.DateTime validTime;
			int day;

			day = time.Day;
			if ((dayStartTime != null) && (dayStartTime.Value.TimeOfDay > time.TimeOfDay))
				time = time.Add(dayStartTime.Value.TimeOfDay.Subtract(time.TimeOfDay));
			if ((dayEndTime != null) && (dayEndTime.Value.TimeOfDay < time.TimeOfDay))
			{
				time = time.AddDays(1);
				return new System.DateTime(time.Year, time.Month, time.Day, 0, 0, 0, System.DateTimeKind.Local);
			}

			if ((lastExecutionTime == null) || (lastExecutionTime.Value.Date < time.Date))
				return time;
			switch (dayFrequencyType)
			{
				case DayFrequencyType.EveryHour:
					if (dayStartTime != null)
					{
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, dayStartTime.Value.Hour,
							dayStartTime.Value.Minute, dayStartTime.Value.Second, System.DateTimeKind.Local);
					}
					else
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, 0, 0, 0, System.DateTimeKind.Local);
					while (validTime <= lastExecutionTime)
						validTime = validTime.AddHours(dayFrequency);
					if (validTime > time)
						time = validTime;
					break;
				case DayFrequencyType.EveryMinute:
					if (dayStartTime != null)
					{
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, dayStartTime.Value.Hour,
							dayStartTime.Value.Minute, dayStartTime.Value.Second, System.DateTimeKind.Local);
					}
					else
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, 0, 0, 0, System.DateTimeKind.Local);
					while (validTime <= lastExecutionTime)
						validTime = validTime.AddMinutes(dayFrequency);
					if (validTime > time)
						time = validTime;
					break;
				case DayFrequencyType.EverySecond:
					if (dayStartTime != null)
					{
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, dayStartTime.Value.Hour,
							dayStartTime.Value.Minute, dayStartTime.Value.Second, System.DateTimeKind.Local);
					}
					else
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, 0, 0, 0, System.DateTimeKind.Local);
					while (validTime <= lastExecutionTime)
						validTime = validTime.AddSeconds(dayFrequency);
					if (validTime > time)
						time = validTime;
					break;
				default:
					if ((dayStartTime != null) && (dayStartTime.Value.TimeOfDay > lastExecutionTime.Value.TimeOfDay))
						return time;
					time = time.AddDays(1);
					break;
			}
			if (time.Day == day)
				return time;
			return new System.DateTime(time.Year, time.Month, time.Day, 0, 0, 0, System.DateTimeKind.Local);
		}

		#endregion
		#region IsExecutionTime

		private static bool IsExecutionTime(System.DateTime? dayStartTime, DayFrequencyType dayFrequencyType, byte dayFrequency, System.DateTime time, System.DateTime? lastExecutionTime)
		{
			System.DateTime validTime;

			if ((lastExecutionTime == null) || (lastExecutionTime.Value.Date < time.Date))
				return true;
			switch (dayFrequencyType)
			{
				case DayFrequencyType.EveryHour:
					if (dayStartTime != null)
					{
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, dayStartTime.Value.Hour,
							dayStartTime.Value.Minute, dayStartTime.Value.Second, System.DateTimeKind.Local);
					}
					else
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, 0, 0, 0, System.DateTimeKind.Local);
					while (validTime <= lastExecutionTime)
						validTime = validTime.AddHours(dayFrequency);
					return time >= validTime;
				case DayFrequencyType.EveryMinute:
					if (dayStartTime != null)
					{
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, dayStartTime.Value.Hour,
							dayStartTime.Value.Minute, dayStartTime.Value.Second, System.DateTimeKind.Local);
					}
					else
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, 0, 0, 0, System.DateTimeKind.Local);
					while (validTime <= lastExecutionTime)
						validTime = validTime.AddMinutes(dayFrequency);
					return time >= validTime;
				case DayFrequencyType.EverySecond:
					if (dayStartTime != null)
					{
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, dayStartTime.Value.Hour,
							dayStartTime.Value.Minute, dayStartTime.Value.Second, System.DateTimeKind.Local);
					}
					else
						validTime = new System.DateTime(lastExecutionTime.Value.Year, lastExecutionTime.Value.Month, lastExecutionTime.Value.Day, 0, 0, 0, System.DateTimeKind.Local);
					while (validTime <= lastExecutionTime)
						validTime = validTime.AddSeconds(dayFrequency);
					return time >= validTime;
				default:
					if ((dayStartTime != null) && (dayStartTime.Value.TimeOfDay > lastExecutionTime.Value.TimeOfDay))
						return true;
					return false;
			}
		}
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
		private static bool IsExecutionTime(MonthFrequencyType monthFrequencyType, byte monthFrequency, System.DateTime time)
		{
			switch (monthFrequencyType)
			{
				case MonthFrequencyType.Monday:
					if (time.DayOfWeek != System.DayOfWeek.Monday)
						return false;
					break;
				case MonthFrequencyType.Tuesday:
					if (time.DayOfWeek != System.DayOfWeek.Tuesday)
						return false;
					break;
				case MonthFrequencyType.Wednesday:
					if (time.DayOfWeek != System.DayOfWeek.Wednesday)
						return false;
					break;
				case MonthFrequencyType.Thursday:
					if (time.DayOfWeek != System.DayOfWeek.Thursday)
						return false;
					break;
				case MonthFrequencyType.Friday:
					if (time.DayOfWeek != System.DayOfWeek.Friday)
						return false;
					break;
				case MonthFrequencyType.Saturday:
					if (time.DayOfWeek != System.DayOfWeek.Saturday)
						return false;
					break;
				case MonthFrequencyType.Sunday:
					if (time.DayOfWeek != System.DayOfWeek.Sunday)
						return false;
					break;
				case MonthFrequencyType.Day:
					return (time.Day == monthFrequency);
				case MonthFrequencyType.Weekday:
					if ((time.DayOfWeek == System.DayOfWeek.Saturday) || (time.DayOfWeek == System.DayOfWeek.Sunday))
						return false;
					break;
				case MonthFrequencyType.Weekend:
					if ((time.DayOfWeek != System.DayOfWeek.Saturday) && (time.DayOfWeek != System.DayOfWeek.Sunday))
						return false;
					break;
				default:
					return false;
			}
			if (monthFrequency > 4)
				return (System.Globalization.CultureInfo.CurrentCulture.Calendar.AddWeeks(time, 1).Month != time.Month);
			else
			{
				if ((System.Globalization.CultureInfo.CurrentCulture.Calendar.AddWeeks(time, -monthFrequency).Month == time.Month) &&
				  (System.Globalization.CultureInfo.CurrentCulture.Calendar.AddWeeks(time, -(monthFrequency + 1)).Month != time.Month))
					return true;
				else
					return false;
			}
		}
		private static bool IsExecutionTime(bool monday, bool tuesday, bool wednesday, bool thursday, bool friday, bool saturday, bool sunday, System.DateTime time)
		{
			if (monday)
			{
				if (time.DayOfWeek == System.DayOfWeek.Monday)
					return true;
			}
			if (tuesday)
			{
				if (time.DayOfWeek == System.DayOfWeek.Tuesday)
					return true;
			}
			if (wednesday)
			{
				if (time.DayOfWeek == System.DayOfWeek.Wednesday)
					return true;
			}
			if (thursday)
			{
				if (time.DayOfWeek == System.DayOfWeek.Thursday)
					return true;
			}
			if (friday)
			{
				if (time.DayOfWeek == System.DayOfWeek.Friday)
					return true;
			}
			if (saturday)
			{
				if (time.DayOfWeek == System.DayOfWeek.Saturday)
					return true;
			}
			if (sunday)
			{
				if (time.DayOfWeek == System.DayOfWeek.Sunday)
					return true;
			}
			return false;
		}

		#endregion
		#region IsExpired

		private static bool IsExpired(System.DateTime startTime, System.DateTime? endDate, System.DateTime time)
		{
			if (endDate == null)
			{
				if (time < startTime.AddYears(10))
					return false;
			}
			else if (time.Date <= endDate.Value.Date)
				return false;
			return true;
		}

		#endregion

		#endregion
	}
}